package cn.mw.cmdb.controller;

import cn.hutool.extra.spring.SpringUtil;
import cn.mw.cmdb.entity.ModelTemplateInfo;
import cn.mw.cmdb.enums.OperatorTypeDescEnum;
import cn.mw.cmdb.param.*;
import cn.mw.cmdb.service.ServiceAction;
import cn.mw.cmdb.service.impl.CmdbServiceManage;
import cn.mw.cmdb.service.impl.ModelTemplateServiceImpl;
import cn.mw.cmdb.view.ViewManager;
import cn.mw.log.client.LogClientSimple;
import cn.mw.log.enums.BusinessLogType;
import cn.mw.log.enums.LogLevel;
import cn.mw.microMonitorCommon.api.common.BaseApiService;
import cn.mw.microMonitorCommon.api.common.ResponseBase;
import cn.mw.microMonitorCommon.constant.Constants;
import cn.mw.microMonitorCommon.security.utils.SecurityUtils;
import cn.mw.microMonitorCommon.util.DateUtils;
import com.google.common.base.Strings;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.stream.Collectors;

import static cn.mw.cmdb.enums.PageDescEnum.ModelTemplate;
import static cn.mw.cmdb.enums.PageDescEnum.Modelinstance;

@RequestMapping("/templateManage")
@Controller
@Tag(name = "模板管理")
@Slf4j
public class TemplateController extends BaseApiService {

    private CmdbServiceManage cmdbServiceManage;
    private final MessageSource messageSource;
    private ViewManager viewManager;
    private LogClientSimple logClientSimple;


    public TemplateController(CmdbServiceManage cmdbServiceManage, MessageSource messageSource, ViewManager viewManager,LogClientSimple logClientSimple) {
        this.cmdbServiceManage = cmdbServiceManage;
        this.messageSource = messageSource;
        this.viewManager = viewManager;
        this.logClientSimple = logClientSimple;
    }

    @PostMapping("/addTemplate")
    @ResponseBody
    @PreAuthorize("@mwAuthorizationCheck.check('299')")
    @Operation(summary = "新增模板")
    public ResponseBase createTemplate(@RequestBody ModelTemplateInfo info) throws Exception {
        cmdbServiceManage.service(info, ServiceAction.add);
        String nickName = SecurityUtils.getUser().getNickName();
        logClientSimple.addBusinessLog(LogLevel.INFO.getId(), BusinessLogType.CMDB_MANAGE.getId(),
                messageSource.getMessage("mwCmdb-operation-log", new Object[]{nickName, DateUtils.now()
                        , BusinessLogType.CMDB_MANAGE.getCnName(), OperatorTypeDescEnum.add.getCname() + ModelTemplate.getDesc(),
                        OperatorTypeDescEnum.add.getCname() + info.getTemplateName(), Constants.OperationStatus.SUCCESS}, LocaleContextHolder.getLocale()));

        return setResultSuccess(messageSource.getMessage("add-success", null, LocaleContextHolder.getLocale()));
    }

    @PostMapping("/updateTemplate")
    @ResponseBody
    @PreAuthorize("@mwAuthorizationCheck.check('300')")
    @Operation(summary = "修改模板")
    public ResponseBase updateTemplate(@RequestBody ModelTemplateInfo info) throws Exception {
        cmdbServiceManage.service(info, ServiceAction.update);
        String nickName = SecurityUtils.getUser().getNickName();
        logClientSimple.addBusinessLog(LogLevel.INFO.getId(), BusinessLogType.CMDB_MANAGE.getId(),
                messageSource.getMessage("mwCmdb-operation-log", new Object[]{nickName, DateUtils.now()
                        , BusinessLogType.CMDB_MANAGE.getCnName(), OperatorTypeDescEnum.update.getCname() + ModelTemplate.getDesc(),
                        OperatorTypeDescEnum.update.getCname() + info.getTemplateName(), Constants.OperationStatus.SUCCESS}, LocaleContextHolder.getLocale()));

        return setResultSuccess(messageSource.getMessage("upd-success", null, LocaleContextHolder.getLocale()));
    }


    @PostMapping("/queryTemplateList")
    @ResponseBody
    @Operation(summary = "查询所有模板列表")
    public ResponseBase queryTemplateList(@RequestBody TemplateSearchParam searchParam) throws Exception {
        long time1 = System.currentTimeMillis();
        List ret = (List) cmdbServiceManage.service(searchParam, ServiceAction.list);
        long time2 = System.currentTimeMillis();
        Object obj = viewManager.getListViewObject(ret, ModelTemplateInfo.class, searchParam, null);
        long time3 = System.currentTimeMillis();
        log.info("获取模板list::aggregateAuthorizedList:" + (time2 - time1) + "ms;转换:" + (time3 - time2) + "ms");
        return setResultSuccess(obj);
    }


    @PostMapping("/queryTemplateById")
    @ResponseBody
    @Operation(summary = "模板查看信息")
    public ResponseBase queryTemplateById(@RequestBody ModelTemplateInfo info) throws Exception {
        Object o = cmdbServiceManage.service(info, ServiceAction.select);
        return setResultSuccess(o);
    }

    @PostMapping("/deleteTemplates")
    @ResponseBody
    @PreAuthorize("@mwAuthorizationCheck.check('301')")
    @Operation(summary = "删除模板")
    public ResponseBase deleteTemplate(@RequestBody TemplateIdsParam info) throws Exception {
        //日志记录
        ModelTemplateServiceImpl modelService = (ModelTemplateServiceImpl) cmdbServiceManage.getModelService(ModelTemplateServiceImpl.ID);
        List<String> ids = info.getIds();
        List<ModelTemplateInfo> templateInfos = modelService.doSelectByIds(ids);
        cmdbServiceManage.service(info, ServiceAction.batchRemove);
        List<String> collect = templateInfos.stream().map(s -> s.getTemplateName()).collect(Collectors.toList());
        String name = String.join(",", collect);
        String nickName = SecurityUtils.getUser().getNickName();
        logClientSimple.addBusinessLog(LogLevel.INFO.getId(), BusinessLogType.CMDB_MANAGE.getId(),
                messageSource.getMessage("mwCmdb-operation-log", new Object[]{nickName, DateUtils.now()
                        , BusinessLogType.CMDB_MANAGE.getCnName(), OperatorTypeDescEnum.remove.getCname() + ModelTemplate.getDesc(),
                        OperatorTypeDescEnum.remove.getCname() + name, Constants.OperationStatus.SUCCESS}, LocaleContextHolder.getLocale()));
        return setResultSuccess(messageSource.getMessage("del-success", null, LocaleContextHolder.getLocale()));
    }

    @PostMapping("/getTemplateListByZabbix")
    @ResponseBody
    @Operation(summary = "获取监控服务器的关联模板")
    public ResponseBase getTemplateListByZabbix() throws Exception {
        ModelTemplateServiceImpl modelService = (ModelTemplateServiceImpl) cmdbServiceManage.getModelService(ModelTemplateServiceImpl.ID);
        List<TemplateZabbixParam> templateListByZabbix = modelService.getTemplateListByZabbix();
        return setResultSuccess(templateListByZabbix);
    }

    @PostMapping("/syncTemplateInfo")
    @ResponseBody
    @PreAuthorize("@mwAuthorizationCheck.check('303')")
    @Operation(summary = "批量更新-同步获取监控服务器上模型数据")
    public ResponseBase syncTemplateInfo() throws Exception {
        ModelTemplateServiceImpl modelService = (ModelTemplateServiceImpl) cmdbServiceManage.getModelService(ModelTemplateServiceImpl.ID);
        modelService.syncTemplateInfo();
        String nickName = SecurityUtils.getUser().getNickName();
        logClientSimple.addBusinessLog(LogLevel.INFO.getId(), BusinessLogType.CMDB_MANAGE.getId(),
                messageSource.getMessage("mwCmdb-operation-log", new Object[]{nickName, DateUtils.now()
                        , BusinessLogType.CMDB_MANAGE.getCnName(), OperatorTypeDescEnum.batchUpd.getCname() + ModelTemplate.getDesc(),
                        OperatorTypeDescEnum.batchUpd.getCname() + "同步监控服务器上模型数据", Constants.OperationStatus.SUCCESS}, LocaleContextHolder.getLocale()));

        return setResultSuccess(messageSource.getMessage("sel-success", null, LocaleContextHolder.getLocale()));
    }

    @PostMapping("/updateTempStatus")
    @ResponseBody
    @PreAuthorize("@mwAuthorizationCheck.check('302')")
    @Operation(summary = "批量修改模板状态")
    public ResponseBase updateTempStatus(@RequestBody TemplateIdsParam info) throws Exception {
        ModelTemplateServiceImpl modelService = (ModelTemplateServiceImpl) cmdbServiceManage.getModelService(ModelTemplateServiceImpl.ID);
        modelService.updateTempStatus(info);
        //日志记录
        List<String> ids = info.getIds();
        List<ModelTemplateInfo> templateInfos = modelService.doSelectByIds(ids);
        List<String> collect = templateInfos.stream().map(s -> s.getTemplateName()).collect(Collectors.toList());
        String name = String.join(",", collect);
        String nickName = SecurityUtils.getUser().getNickName();
        logClientSimple.addBusinessLog(LogLevel.INFO.getId(), BusinessLogType.CMDB_MANAGE.getId(),
                messageSource.getMessage("mwCmdb-operation-log", new Object[]{nickName, DateUtils.now()
                        , BusinessLogType.CMDB_MANAGE.getCnName(), OperatorTypeDescEnum.batchUpd.getCname() + ModelTemplate.getDesc(),
                        OperatorTypeDescEnum.batchUpd.getCname() +name, Constants.OperationStatus.SUCCESS}, LocaleContextHolder.getLocale()));
        return setResultSuccess(messageSource.getMessage("upd-success", null, LocaleContextHolder.getLocale()));
    }

    @PostMapping("/importTempByExcel")
    @ResponseBody
    @PreAuthorize("@mwAuthorizationCheck.check('304')")
    @Operation(summary = "导入Excel模板数据")
    public void importTempByExcel(@RequestBody MultipartFile file, HttpServletResponse response) throws Exception {
        ModelTemplateServiceImpl modelService = (ModelTemplateServiceImpl) cmdbServiceManage.getModelService(ModelTemplateServiceImpl.ID);
        List<TemplateExcelImportParam> templateExcelImportParams = modelService.importTempByExcel(file, response);

        //没有错误信息，表示导入全部成功
        String message ="";
        if(CollectionUtils.isNotEmpty(templateExcelImportParams)){
            for(int x = 0;x<templateExcelImportParams.size();x++){
                if(!Strings.isNullOrEmpty(templateExcelImportParams.get(x).getErrorMsg())){
                    message += "第"+(x+1)+"行"+templateExcelImportParams.get(x).getErrorMsg()+";";
                }
            }
        }else{
            message = "导入成功";
        }
        String nickName = SecurityUtils.getUser().getNickName();
        logClientSimple.addBusinessLog(LogLevel.INFO.getId(), BusinessLogType.CMDB_MANAGE.getId(),
                messageSource.getMessage("mwCmdb-operation-log", new Object[]{nickName, DateUtils.now()
                        , BusinessLogType.CMDB_MANAGE.getCnName(), OperatorTypeDescEnum.batchImport.getCname() + ModelTemplate.getDesc(),
                        OperatorTypeDescEnum.batchImport.getCname() + message, Constants.OperationStatus.SUCCESS}, LocaleContextHolder.getLocale()));
    }

    @PostMapping("/exportTempByExcel")
    @ResponseBody
    @PreAuthorize("@mwAuthorizationCheck.check('305')")
    @Operation(summary = "导出资产模板数据")
    public void exportTempByExcel(@RequestBody TemplateSearchParam searchParam, HttpServletRequest request, HttpServletResponse response) throws Exception {
        ModelTemplateServiceImpl modelService = (ModelTemplateServiceImpl) cmdbServiceManage.getModelService(ModelTemplateServiceImpl.ID);
        int num = modelService.exportTempByExcel(searchParam, request, response);
        String nickName = SecurityUtils.getUser().getNickName();
        logClientSimple.addBusinessLog(LogLevel.INFO.getId(), BusinessLogType.CMDB_MANAGE.getId(),
                messageSource.getMessage("mwCmdb-operation-log", new Object[]{nickName, DateUtils.now()
                        , BusinessLogType.CMDB_MANAGE.getCnName(), OperatorTypeDescEnum.batchExport.getCname() + ModelTemplate.getDesc(),
                        OperatorTypeDescEnum.batchExport.getCname() +num+"条资产数据", Constants.OperationStatus.SUCCESS}, LocaleContextHolder.getLocale()));


    }

    @PostMapping("/exportExcelTemplate")
    @ResponseBody
    @PreAuthorize("@mwAuthorizationCheck.check('306')")
    @Operation(summary = "导出模板Excel格式")
    public ResponseBase exportExcelTemplate(@RequestBody TemplateSearchParam searchParam, HttpServletRequest request, HttpServletResponse response) throws Exception {
        searchParam.setExportTemp(true);
        ModelTemplateServiceImpl modelService = (ModelTemplateServiceImpl) cmdbServiceManage.getModelService(ModelTemplateServiceImpl.ID);
        modelService.exportTempByExcel(searchParam, request, response);
        return setResultSuccess(messageSource.getMessage("export-success", null, LocaleContextHolder.getLocale()));
    }

    @PostMapping("/selectTempInfoAndMonitorMode")
    @ResponseBody
    @Operation(summary = "获取模板信息和对应的监控方式")
    public ResponseBase selectTempInfoAndMonitorMode(@RequestBody ModelTemplateInfo info) throws Exception {
        ModelTemplateServiceImpl modelService = (ModelTemplateServiceImpl) cmdbServiceManage.getModelService(ModelTemplateServiceImpl.ID);
        List<QueryModelTemplateParam> templateInfos = modelService.selectTempInfoAndMonitorMode(info);
        return setResultSuccess(templateInfos);
    }

    @PostMapping("/selectMonitorModeByTemplateName")
    @ResponseBody
    @Operation(summary = "根据模板名称查询监控方式")
    public ResponseBase selectMonitorModeByTemplateName(@RequestBody QueryModelTemplateParam param) throws Exception {
        ModelTemplateServiceImpl modelService = (ModelTemplateServiceImpl) cmdbServiceManage.getModelService(ModelTemplateServiceImpl.ID);
        List<MwModelLabelValueParam> templateInfos = modelService.selectMonitorModeByTemplateName(param);
        return setResultSuccess(templateInfos);
    }

    @PostMapping("/getTempDescrInfo")
    @ResponseBody
    @Operation(summary = "获取模板的描述信息")
    public ResponseBase getTempDescrInfo(@RequestBody TemplateSearchParam param) throws Exception {
        ModelTemplateServiceImpl modelService = (ModelTemplateServiceImpl) cmdbServiceManage.getModelService(ModelTemplateServiceImpl.ID);
        String descrInfo = modelService.getTempDescrInfo(param);
        return setResultSuccess(descrInfo);
    }

    @PostMapping("/getMacInfoByTemplate")
    @ResponseBody
    @Operation(summary = "根据模板名称的获取宏值字段")
    public ResponseBase getMacInfoByTemplate(@RequestBody TemplateSearchParam param) throws Exception {
        ModelTemplateServiceImpl modelService = (ModelTemplateServiceImpl) cmdbServiceManage.getModelService(ModelTemplateServiceImpl.ID);
        List<MwMacros> macInfoByTemplate = modelService.getMacInfoByTemplate(param);
        return setResultSuccess(macInfoByTemplate);
    }

}
